package org.framework.common.cui;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.framework.common.api.entity.CommonEntityAware;
import org.framework.common.api.service.bo.CommonBoAware;
import org.framework.common.api.support.model.FileModel;
import org.framework.common.api.support.model.FormModel;
import org.framework.common.api.support.model.ProcessModel;
import org.framework.common.api.support.model.QueryModel;
import org.framework.common.ext.util.ClassUtil;
import org.framework.common.ext.util.StringUtil;
import org.framework.common.ext.util.datasource.DynamicDataSource;
import org.framework.common.ext.util.datasource.DynamicDataSourceHolder;
import org.jboss.logging.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.ui.ModelMap;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public abstract class AbstractController implements ApplicationContextAware {

	private static Logger log = Logger.getLogger(AbstractController.class);

	private static final String DB_FILE_PATH = "classpath:config/spring/dbsource/{dbname}.xml";
	private static final String SUCCESS = "success";
	private static final String ERROR = "error";
	private static final String DEFAULT_DBNAME = "default";
	private static final String DEFAULT_DATASOURCE = "defaultDataSource";
	
	protected static final String USER_LOGINED_SESSION = "logined.user";
	protected static final String STATUS_DEFAULT = "0";
	protected static final String INVALID_TRUE = "T";
	protected static final String INVALID_FALSE = "F";
	
	protected static final int RETURN_ERROR = 500;
	protected static final int RETURN_INVALID = 400;
	protected static final int RETURN_SUCCESS = 200;
	
	protected static final String RETURN_ERROR_MESSAGE = "接口调用失败，系统异常！";
	protected static final String RETURN_INVALID_MESSAGE = "接口调用失败，参数错误！";
	protected static final String RETURN_SUCCESS_MESSAGE = "接口调用成功！";
	
	// 公共业务对象
	@Resource(name = "defaultBo")
	protected CommonBoAware<CommonEntityAware<String>, String> bo;
	
	// 线程池
	@Autowired
	protected ThreadPoolTaskExecutor executor;
		
	// 动态数据源
	@Autowired
	protected DynamicDataSource dynamic;
		
	// JDBC模版
	@Autowired
	protected JdbcTemplate jdbc;
	
	// 响应对象
	@Autowired
	protected HttpServletResponse response;
	
	// 请求对象
	@Autowired
	protected HttpServletRequest request;
	
	// 上下文对象
	protected ApplicationContext context;
	
	/**
	 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
	 * @author chanlong(陈龙)
	 * @date 2016年9月6日 上午11:48:10
	 */
	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
		this.context = context;
		
		// 获取默认数据源
        ComboPooledDataSource dataSource = (ComboPooledDataSource) context.getBean(DEFAULT_DATASOURCE);
        
        // 添加默认数据源
        dynamic.addDataSource(DEFAULT_DBNAME, dataSource);
	}
	
	/** 构造自定义键值对返回结果 **/
	public Map<String, Object> result;
	public AbstractController addProperty(final String key, final Object value){
		if(result == null) result = new LinkedHashMap<String, Object>();
		result.put(key, value);
		return this;
	}
	
	/**
	 * 注册数据源.
	 * @param dbname
	 * @author chanlong(陈龙)
	 * @date 2016年1月14日 下午5:13:33
	 */
	public void registerDataSource(final String dbname){
		String source = DEFAULT_DATASOURCE;
		String dbskey = DEFAULT_DBNAME;
		
		if(StringUtil.isNotEmpty(dbname) && !dbname.equals(DEFAULT_DBNAME)){
			source = dbskey = dbname;
		}
		
		if(StringUtil.isNotEmpty(dbname) && !dynamic.hasDataSource(dbskey)){
			// 加载数据源
			dynamic.loaderBean(DB_FILE_PATH.replace("{dbname}", dbname));
			
			// 获取数据源
	        ComboPooledDataSource dataSource = (ComboPooledDataSource) context.getBean(source);

	        // 添加数据源
	        dynamic.addDataSource(dbskey, dataSource);
		}
		
		// 切换数据源
		DynamicDataSourceHolder.setDataSource(dbskey);
		
		// 注册业务操作辅助对象
		ProcessModel.factory().registerProcess(bo, jdbc, executor);
		
		System.out.println("current dynamic dbsource : " + DynamicDataSourceHolder.getDataSource());
	}
	
	/**
	 * spring mvc 返回json对象.
	 * @param entity
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年7月10日  下午5:17:29
	 */
	protected ModelMap json(final Object obj){
		return new ModelMap().addAllAttributes(ClassUtil.getProperties(obj));
	}
	
	/**
	 * 获取接口调用接口的数据内容.
	 * @param key
	 * @param value
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月2日 上午11:36:58
	 */
	protected Object getResultData(final String key, final Object value){
		Map<String, Object> data = new HashMap<>();
		if(StringUtil.isEmpty(key) && StringUtil.isNotEmpty(value)){
			return value;
		}else if(StringUtil.isEmpty(value)){
			data.put("result", "empty");
		}else{
			data.put(key, value);
		}
		return data;
	}
	
	/**
	 * 成功.
	 * @param result
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年5月9日 下午3:57:18
	 */
	protected Map<String, Object> success(final int code, final String message){
		Map<String, Object> backMap = new HashMap<>();
        backMap.put("resultCode", code);
        backMap.put("resultMessage", message);
		return backMap;
	}
	
	/**
	 * 成功.
	 * @param result
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年5月9日 下午3:57:18
	 */
	protected Map<String, Object> success(final int code, final String message, final Throwable e){
		log.error(message, e);
		
		Map<String, Object> backMap = new HashMap<>();
        backMap.put("resultCode", code);
        backMap.put("resultMessage", message);
		return backMap;
	}
	
	/**
	 * 成功.
	 * @param result
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年5月9日 下午3:57:18
	 */
	protected Map<String, Object> success(final int code, final String message, final Object data){
		Map<String, Object> backMap = new HashMap<>();
        backMap.put("resultCode", code);
        backMap.put("resultMessage", message);
        
        backMap.put("data", getResultData(null, data));  
		return backMap;
	}
	
	/**
	 * 成功.
	 * @param result
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年5月9日 下午3:57:18
	 */
	protected Map<String, Object> success(final boolean result, final Object message){
		Map<String, Object> backMap = new HashMap<>();
		backMap.put("data", message);  
        backMap.put("success", result);
		return backMap;
	}
	
	/**
	 * 成功.
	 * @param result
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年5月9日 下午3:57:18
	 */
	protected Map<String, Object> success(final boolean result, final Object message, final Exception e){
		log.error(message, e);
		
		Map<String, Object> backMap = new HashMap<>();
		backMap.put("data", message);  
        backMap.put("success", result);
		return backMap;
	}
	
	/**
	 * 成功.
	 * @param entity
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年7月10日  下午8:21:37
	 */
	protected ModelMap success(final Object obj){
		request.getSession().setAttribute(obj.getClass().getName(), obj);
		return new ModelMap().addAttribute(SUCCESS, obj);
	}
	
	/**
	 * 成功.
	 * @param result
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年2月8日 下午3:25:43
	 */
	protected ModelMap success(final Integer result){
		return new ModelMap().addAttribute(SUCCESS, result);
	}
	
	/**
	 * 成功.
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年7月10日  下午8:46:04
	 */
	protected ModelMap success(final String message){
		return new ModelMap().addAttribute(SUCCESS, message);
	}
	
	/**
	 * 错误.
	 * @param message
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年7月10日  下午5:12:09
	 */
	protected ModelMap error(final String message){
		return new ModelMap().addAttribute(ERROR, message);
	}
	
	/**
	 * 错误.
	 * @param message
	 * @param e
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年7月10日  下午5:17:06
	 */
	protected ModelMap error(final String message, final Exception e){
		log.error(message, e);
		return new ModelMap().addAttribute("error", message);
	}
	
	/**
	 * 检查文件模型参数.
	 * @param query
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年1月19日 下午3:07:12
	 */
	protected boolean check(final FileModel model){
		try{
			return model.getFile() == null && model.getFiles() == null;
		}catch(NullPointerException e){
			return true;
		}
	}
	
	/**
	 * 检查表单模型参数.
	 * @param model
	 * @return 对象或参数为空返回true
	 * @author chanlong(陈龙)
	 * @date 2014年7月10日  下午8:39:23
	 */
	protected boolean check(final FormModel model){
		try{
			return model.getBean() == null;
		}catch(NullPointerException e){
			return true;
		}
	}
	
	/**
	 * 检查查询模型参数.
	 * @param query
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年1月19日 下午3:07:12
	 */
	protected boolean check(final QueryModel model){
		try{
			return check(model.getEntityClass());
		}catch(NullPointerException e){
			return true;
		}
	}
	
	/**
	 * 检查一般参数.
	 * @param dbname
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年1月16日 上午11:07:40
	 */
	protected boolean check(final String param){
		try{
			return StringUtil.isEmpty(param) || "{dbname}".equals(param);
		}catch(NullPointerException e){
			return true;
		}
	}
}
